using System.Text;
using imitateMacQQ.WebApi.Api.WebSocket;
using imitateMacQQ.WebApi.Configures;
using imitateMacQQ.WebApi.Domain.CircleServe.Interface;
using imitateMacQQ.WebApi.Domain.CircleServe.Service;
using imitateMacQQ.WebApi.Domain.FirstCode.schema;
using imitateMacQQ.WebApi.Domain.Friend.module.Interface;
using imitateMacQQ.WebApi.Domain.Friend.module.Service;
using imitateMacQQ.WebApi.Domain.Login.register.Login.Interface;
using imitateMacQQ.WebApi.Domain.Login.register.Login.Service;
using imitateMacQQ.WebApi.Domain.Login.register.utils;
using imitateMacQQ.WebApi.Domain.Modifying_User_Information.Interface;
using imitateMacQQ.WebApi.Domain.Modifying_User_Information.Service;
using imitateMacQQ.WebApi.Domain.real_time.communication.Interface;
using imitateMacQQ.WebApi.Domain.real_time.communication.Service;
using imitateMacQQ.WebApi.Domain.RealTime.Interface;
using imitateMacQQ.WebApi.Domain.RealTime.Service;
using imitateMacQQ.WebApi.Domain.Token.wand.Token.Interface;
using imitateMacQQ.WebApi.Domain.Token.wand.Token.Service;
using imitateMacQQ.WebApi.Domain.Token.wand.utils;
using imitateMacQQ.WebApi.Domain.utils;
using imitateMacQQ.WebApi.Repository.EFCore.Model.utils;
using imitateMacQQ.WebApi.Repository.EFCore.transform;
using imitateMacQQ.WebApi.Repository.Redis;
using imitateMacQQ.WebApi.Repository.Redis.Interface;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.Extensions.FileProviders;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using NLog.Web;


var builder = WebApplication.CreateBuilder(args);

var configuration = builder.Configuration;
await Admin.Init(configuration);

builder.Logging.AddNLog("Configures/NLog.config");
builder.Services.AddControllers(options =>
    options.Filters.Add(typeof(CustomerGlobalExceptionFilterAsync)));
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer(); //最低限度API
builder.Services.AddSwaggerGen(s =>
{
    s.SwaggerDoc("v1", new OpenApiInfo { Title = "ImitateMacQQ", Version = "v1" });
    s.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
    {
        Description = "在下框中输入请求头中需要添加Jwt授权Token：Bearer Token",
        Name = "Authorization",
        In = ParameterLocation.Header,
        Type = SecuritySchemeType.ApiKey,
        BearerFormat = "JWT",
        Scheme = "Bearer"
    });
    s.AddSecurityRequirement(new OpenApiSecurityRequirement
    {
        {
            new OpenApiSecurityScheme
            {
                Reference = new OpenApiReference
                {
                    Type = ReferenceType.SecurityScheme,
                    Id = "Bearer"
                }
            },
            Array.Empty<string>()
        }
    });
});
builder.Services.AddCors(options =>
{
    options.AddPolicy(name: "myCors",
        build =>
        {
            build.WithOrigins("*", "*", "*")
                .AllowAnyOrigin()
                .AllowAnyHeader()
                .AllowAnyMethod();
        });
});
builder.Services.AddAuthentication(options => { options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; })
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters()
        {
            ValidateIssuer = true, //是否验证Issuer
            ValidIssuer = configuration["Jwt:Issuer"], //发行人
            ValidateAudience = true, //    是否验证Audience
            ValidAudience = configuration["Jwt:Audience"], //订阅人 Audience
            ValidateIssuerSigningKey = true, //是否验证SecurityKey
            IssuerSigningKey = new SymmetricSecurityKey(
                Encoding.UTF8.GetBytes(configuration["Jwt:SecretKey"])),
            //  SecurityKey
            ValidateLifetime = true, //是否验证失效时间
            ClockSkew = TimeSpan.FromSeconds(30), //过期容错值，解决服务器时间不同步问题
            RequireExpirationTime = true, //不包含“过期”值，则将其视为无效
        };
    });
var section = configuration.GetSection("Redis:Default");
var connectionString = section.GetSection("Connection").Value ?? "127.0.0.1:6379";
var instanceName = section.GetSection("InstanceName").Value ?? "local";
var defaultDb = int.Parse(section.GetSection("DefaultDB").Value ?? "8");

builder.Services.AddSingleton(new RedisHelper(connectionString, instanceName, defaultDb));
builder.Services.AddSingleton<IGetTokenService, RegisterBeforeAffirm>();
builder.Services.AddSingleton<IDesign, DesignService>();
builder.Services.AddSingleton(new Utils(configuration));
builder.Services.AddSingleton<IFriend, FriendService>();
builder.Services.AddSingleton<IGetAccessTokenUsedRefreshToken, ApplyForTokenAgain>();
builder.Services.AddSingleton(new JwtHelper(configuration));
builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
builder.Services.AddSingleton<INLogHelper, NLogHelper>();
builder.Services.AddSingleton<IReleaseInfo, ReleaseService>();
builder.Services.AddSingleton<IUpvote, UpvoteService>();
builder.Services.AddSingleton<ITalkInfo, TalkService>();
builder.Services.AddSingleton<IGetCircle, GetCircleService>();
builder.Services.AddScoped<IGetFriendMes, GetMesService>();
// builder.Services.AddSingleton(new DataDbContext());
builder.Services.AddScoped<IRegisterTools, RegisterTools>();
builder.Services.AddScoped<IUserInfoService, UserInfoService>();
builder.Services.AddScoped<IRegisterFromInfoResult, RegisterNewUser>();
builder.Services.AddScoped<IMessager, Messager>();
builder.Services.AddTransient<ISqlLinkRedis, SqlLinkRedis>();
builder.Services.AddTransient<IUploadService, UploadService>();
builder.Services.AddTransient<IGetLoginCode, GetLoginCode>();
builder.Services.AddTransient<UtilsTime>();

builder.Services.AddHostedService<TestHostedService>();


var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(
        Path.Combine(Directory.GetCurrentDirectory(),
            "StaticFiles"))
}); //文件服务

app.UseCors("myCors");
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers();
app.UseWebSockets();
app.Run();